﻿#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;

    using Csla;
    using Csla.Core;
    using Csla.Data;
    using Csla.Reflection;
    using Csla.Security;
    using Csla.Server;

    using MarketPulse.DataAccess;
    using MarketPulse.Reporting.Core;
    using MarketPulse.Reporting.Core.Criteria;

    using MarketPulse.DataAccess.DataContextObjects.ReportingMcDonalds;
    using MarketPulse.DataAccess.DataContextObjects.Production;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Abstracts the data access for the Security away from the Security Business Objects.
    /// </summary>
    public class McDonaldsDashBoardFactory : ObjectFactory
    {

        #region Member Variables

            /// <summary>Property that stores the name of the class.</summary>
            private static readonly Type mClass = MethodBase.GetCurrentMethod().DeclaringType;

            /// <summary>Property that stores the log4net logger for this class.</summary>
            private static readonly log4net.ILog mLog = log4net.LogManager.GetLogger(mClass);
            private object reportingVisitInfo = null;

        #endregion

        #region Methods

            /// <summary>
            /// Method used to fetch a list of read-only ReportingVisitInfo objects.      
            /// </summary>
            /// <param name="criteria">The criteria object holding the values used to retrieve the list</param>
            /// <returns>An read-only list of ReportingVisitInfo objects retrieved from the database</returns>
            public McDonaldsCSOScoreSummaryReportInfoList FetchSummaryInfoList(DashboardReportCriteria criteria)
            {
                try
                {
                    using (var mcDonaldsReportingManager = ContextManager<ReportingMcDonalds_dev>.GetManager(Database.McDonaldsReportingSystem))
                    {
                        var mcDonaldsCSOScoreSummaryReportInfoList = (McDonaldsCSOScoreSummaryReportInfoList)MethodCaller.CreateInstance(typeof(McDonaldsCSOScoreSummaryReportInfoList));
                        SetIsReadOnly(mcDonaldsCSOScoreSummaryReportInfoList, false);

                        var uspYTDScoresSummarySelect = mcDonaldsReportingManager.DataContext.UspYTDScoresSummary(
                                                                                                criteria.BranchGUIDList,
                                                                                                criteria.AsOfDate,
                                                                                                criteria.LanguageCode,
                                                                                                criteria.Published);

                        foreach (var result in uspYTDScoresSummarySelect)
                        {
                            var mcDonaldsCSOScoreSummaryReportInfo = (McDonaldsCSOScoreSummaryReportInfo)MethodCaller.CreateInstance(typeof(McDonaldsCSOScoreSummaryReportInfo));

                            // Load scores, ranks and visits summary info
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.YTDDineInScoreProperty, result.YTDDineInScore);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.YTDDriveThruScoreProperty, result.YTDDriveThruScore);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.YTDOverAllScoreProperty, result.YTDOverAllScore);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.YTDCurrentPeriodRankProperty, result.YTDCurrentPeriodRank);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.YTDPeriodRanksTotalProperty, result.YTDPeriodRanksTotal);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.DineInVisitsCompletedCurrentRoundProperty, result.DineInVisitsCompletedCurrentRound);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.DriveThruVisitsCompletedCurrentRoundProperty, result.DriveThruVisitsCompletedCurrentRound);
                            LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.OverAllVisitsCompletedCurrentRoundProperty, result.OverAllVisitsCompletedCurrentRound);

                            // Reset visits required counts for DineIn/DriveThru/OverAll for the current round (rallydev requirement)
                            var visitsRequired = McDonaldsVisitsRequiredReportInfoList.GetScoreTrendingReport(criteria);
                            if (visitsRequired.Count > 0)
                            {
                                var resultVR = visitsRequired.Single();
                                LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.DineInVisitsRequiredCurrentRoundProperty, resultVR.DineInVisitsRequired);
                                LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.DriveThruVisitsRequiredCurrentRoundProperty, resultVR.DriveThruVisitsRequired);
                                LoadProperty(mcDonaldsCSOScoreSummaryReportInfo, McDonaldsCSOScoreSummaryReportInfo.OverAllVisitsRequiredCurrentRoundProperty, resultVR.OverallVisitsRequired);
                            }

                            // Let Csla know this object has changed
                            MarkOld(mcDonaldsCSOScoreSummaryReportInfo);

                            // Append the item
                            mcDonaldsCSOScoreSummaryReportInfoList.Add(mcDonaldsCSOScoreSummaryReportInfo);

                            // Set the collection back to read only
                            SetIsReadOnly(mcDonaldsCSOScoreSummaryReportInfo, true);
                        }

                        // Let Csla this object has changed since instantiation.
                        MarkOld(mcDonaldsCSOScoreSummaryReportInfoList);

                        return mcDonaldsCSOScoreSummaryReportInfoList;
                    }
                }
                catch (InvalidOperationException ioe)
                {
                    throw ioe;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            /// <summary>
            /// Method used to fetch a list of read-only ReportingVisitInfo objects.
            /// </summary>
            /// <param name="criteria">The criteria object holding the values used to retrieve the list</param>
            /// <returns>An read-only list of ReportingVisitInfo objects retrieved from the database</returns>
            public McDonaldsVisitsRequiredReportInfoList FetchVisitsRequiredInfoList(DashboardReportCriteria criteria)
            {
                try
                {
                    using (var productionManager = ContextManager<MUM_dev>.GetManager(Database.BusinessSystem))
                    {
                        var mcDonaldsVisitsRequiredReportInfoList = (McDonaldsVisitsRequiredReportInfoList)MethodCaller.CreateInstance(typeof(McDonaldsVisitsRequiredReportInfoList));
                        SetIsReadOnly(mcDonaldsVisitsRequiredReportInfoList, false);

                        var uspVisitsRequiredByRoundOfADateSelect = productionManager.DataContext.UspVisitsRequiredByRoundOfADate(
                                                                                                criteria.BranchGUIDList,
                                                                                                criteria.AsOfDate);

                        foreach (var result in uspVisitsRequiredByRoundOfADateSelect)
                        {
                            var mcDonaldsVisitsRequiredReportInfo = (McDonaldsVisitsRequiredReportInfo)MethodCaller.CreateInstance(typeof(McDonaldsVisitsRequiredReportInfo));

                            // Reset visits required counts for DineIn/DriveThru/OverAll for the current round (rallydev requirement)
                            LoadProperty(mcDonaldsVisitsRequiredReportInfo, McDonaldsVisitsRequiredReportInfo.DineInVisitsRequiredProperty, result.DineInVisitsRequired);
                            LoadProperty(mcDonaldsVisitsRequiredReportInfo, McDonaldsVisitsRequiredReportInfo.DriveThruVisitsRequiredProperty, result.DriveThruVisitsRequired);
                            LoadProperty(mcDonaldsVisitsRequiredReportInfo, McDonaldsVisitsRequiredReportInfo.OverallVisitsRequiredProperty, result.OverallVisitsRequired);

                            // Let Csla know this object has changed
                            MarkOld(mcDonaldsVisitsRequiredReportInfo);

                            // Append the item
                            mcDonaldsVisitsRequiredReportInfoList.Add(mcDonaldsVisitsRequiredReportInfo);

                            // Set the collection back to read only
                            SetIsReadOnly(mcDonaldsVisitsRequiredReportInfo, true);
                        }

                        // Let Csla this object has changed since instantiation.
                        MarkOld(mcDonaldsVisitsRequiredReportInfoList);

                        return mcDonaldsVisitsRequiredReportInfoList;
                    }
                }
                catch (InvalidOperationException ioe)
                {
                    throw ioe;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            /// <summary>
            /// Method used to fetch a list of read-only ReportingVisitInfo objects.
            /// </summary>
            /// <param name="criteria">The criteria object holding the values used to retrieve the list</param>
            /// <returns>An read-only list of ReportingVisitInfo objects retrieved from the database</returns>
            public McDonaldsCSOTrendingReportInfoList FetchInfoList(DashboardReportCriteria criteria)
            {
                try
                {
                    using (var mcDonaldsReportingManager = ContextManager<ReportingMcDonalds_dev>.GetManager(Database.McDonaldsReportingSystem))
                    {
                        var mcDonaldsCSOTrendingReportInfoList = (McDonaldsCSOTrendingReportInfoList)MethodCaller.CreateInstance(typeof(McDonaldsCSOTrendingReportInfoList));
                        SetIsReadOnly(mcDonaldsCSOTrendingReportInfoList, false);

                        var uspDataSetSiteReportTotalScoreTrendingSelect = mcDonaldsReportingManager.DataContext.UspTTMScoreTrending(
                                                criteria.BranchGUIDList,
                                                criteria.AsOfDate,
                                                criteria.LanguageCode,
                                                criteria.Published,
                                                criteria.ExcludeDecember,
                                                false);

                        foreach (var result in uspDataSetSiteReportTotalScoreTrendingSelect)
                        {
                            var mcDonaldsCSOTrendingReportInfo = (McDonaldsCSOTrendingReportInfo)MethodCaller.CreateInstance(typeof(McDonaldsCSOTrendingReportInfo));

                            // Load properties
                            LoadProperty(mcDonaldsCSOTrendingReportInfo, McDonaldsCSOTrendingReportInfo.YearPeriodProperty, result.YearPeriod);
                            LoadProperty(mcDonaldsCSOTrendingReportInfo, McDonaldsCSOTrendingReportInfo.ComponentLabelProperty, result.ComponentLabel);
                            LoadProperty(mcDonaldsCSOTrendingReportInfo, McDonaldsCSOTrendingReportInfo.CSOscoreProperty, result.CSOscore);

                            // Let Csla know this object has changed
                            MarkOld(mcDonaldsCSOTrendingReportInfo);

                            // Append the item
                            mcDonaldsCSOTrendingReportInfoList.Add(mcDonaldsCSOTrendingReportInfo);

                            // Set the collection back to read only
                            SetIsReadOnly(mcDonaldsCSOTrendingReportInfo, true);
                        }

                        // Let Csla this object has changed since instantiation.
                        MarkOld(mcDonaldsCSOTrendingReportInfoList);
                        return mcDonaldsCSOTrendingReportInfoList;
                    }
                }
                catch (InvalidOperationException ioe)
                {
                    //TODO log exception appropriately before re throwing
                    throw ioe;
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }

        #endregion
    }
}
